package com.unytech.project.web.action.system;

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.Properties;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;

import com.google.code.kaptcha.Producer;
import com.unytech.project.annotation.ActionLabel;
import com.unytech.project.annotation.ActionMethodLabel;
import com.unytech.project.annotation.enumerate.InterceptLevel;
import com.unytech.project.common.Globals;
import com.unytech.project.entity.system.Permission;
import com.unytech.project.entity.system.User;
import com.unytech.project.service.system.PermissionService;
import com.unytech.project.service.system.UserService;
import com.unytech.project.utils.MD5Util;
import com.unytech.project.utils.PermissionUtil;
import com.unytech.project.utils.PropertiesUtils;
import com.unytech.project.utils.VerifyCodeFactory;
import com.unytech.project.web.action.BaseAction;
/**
 * 处理关于系统管理的一些请求
 * @author DolphinBoy
 *
 */

@ActionLabel(module="系统模块")
public class SystemAction extends BaseAction {
	private String adminname;
	private String adminpwd;
	private String[] authorizationcode;
	private String verifycode;

	private String codelength;
	private String codewidth;
	private String codeheight;
	
	@Resource private UserService userService;
	@Resource private PermissionService permissionService;
	
	/**
	 * 这个方法要实现同步，也就是说如果一个请求正在访问这个方法，则次方法将被锁定，不允许在被其他请求访问
	 * 暂未实现
	 * 此方法的名字请勿在其他Action中使用，这关系到系统拦截器中对此方法的特殊拦截处理，如果要更改名字那么请读改系统拦截器代码
	 */
	@ActionMethodLabel(intercept=InterceptLevel.PUBLIC, methodnote="初始化系统")
	public String initSystem() throws Exception{
		if (adminname == null || !adminname.equals(systemParams.getAdminname())) {
			addActionMessage("超级管理员名称错误");
			return INITSYSTEM_VIEW;
		}
		MD5Util MD5 = new MD5Util();
		if (adminpwd == null || !MD5.getMD5ofStr(adminpwd).equals(systemParams.getAdminpwd())) {
			addActionMessage("超级管理员密码错误");
			return INITSYSTEM_VIEW;
		}
		
		String unytechauthorizationcode = authorizationcode[0]+authorizationcode[1]+authorizationcode[2]+authorizationcode[3];
		if (unytechauthorizationcode == null || !unytechauthorizationcode.equals(systemParams.getUnytechauthorizationcode())) {
			addActionMessage("授权代码错误");
			return INITSYSTEM_VIEW;
		}

		if (verifycode == null || !verifycode.equals(getSession().getAttribute(Globals.SESSION_VERIFYCODE_KEY))) {
			addActionMessage("验证码错误");
			return INITSYSTEM_VIEW;
		}
		
		User user = null;
		try {
			user = userService.loginVerify(systemParams.getAdminname(), systemParams.getAdminpwd());
		} catch (Exception e) {
			errorrecord.setErrordescribe("初始化系统：根据用户名和密码查询用户是否存在时产生例外");
			getSession().setAttribute(Globals.SESSION_ERRORRECORD, errorrecord);
			throw e;
		}
		if (user == null) {
			User adminuser = new User();
			adminuser.setUsername(systemParams.getAdminname());
			adminuser.setPassword(systemParams.getAdminpwd());
//			adminuser.setRealname("系统超级管理员");
			adminuser.setRegdate(new Date());
			try {
				userService.save(adminuser);
			} catch (Exception e) {
				errorrecord.setErrordescribe("初始化系统：写入超级管理员到数据库时产生例外");
				getSession().setAttribute(Globals.SESSION_ERRORRECORD, errorrecord);
				throw e;
			}
		}
		
		long permsum = 0;
		try {
			permsum = permissionService.getCount();
		} catch (Exception e) {
			errorrecord.setErrordescribe("初始化系统：查询数据库中所有的权限时产生例外");
			getSession().setAttribute(Globals.SESSION_ERRORRECORD, errorrecord);
			throw e;
		}
		
		List<Permission> permissionlist = PermissionUtil.getXMLPermission();
		if (permissionlist == null || permissionlist.size() == 0) {	
			addActionMessage("初始化系统：未从权限文件中查找到任何权限，请联系开发人员！");
			return MESSAGE_VIEW;
		}
		
		String permidi = null;
		for (int i=0;i<permissionlist.size();i++) {
			permidi = permissionlist.get(i).getPermid();
			for (int j=i+1;j<permissionlist.size();j++) {
				if (permidi.equals(permissionlist.get(j).getPermid())) {
					addActionMessage("初始化系统：检测权限文件时发现有重复的键值");
					logger.info("重复键值-->"+permidi+":"+permissionlist.get(j).getPermid());
					return MESSAGE_VIEW;
				}
			}
		}
		
		//更新全局变量中的所以权限信息
		getServletContext().setAttribute(Globals.CONTEXT_ALLPERMISSIONS_KEY, permissionlist);
		
		if (permsum >0 && permsum < permissionlist.size()) {
			try {
				permissionService.deleteAll();
			}
			catch (Exception e) {
				errorrecord.setErrordescribe("初始化系统：删除数据库中不完整的权限时产生例外");
				getSession().setAttribute(Globals.SESSION_ERRORRECORD, errorrecord);
				throw e;
			}
		}
		try {
			permissionService.saveAll(permissionlist);
		} catch (Exception e) {
			errorrecord.setErrordescribe("初始化系统：保存所有的系统权限到数据库时产生例外");
			getSession().setAttribute(Globals.SESSION_ERRORRECORD, errorrecord);
			throw e;
		}
		
		//更改系统配置文件变量值
		Properties proper = new Properties();
		proper.setProperty("sysparams.systeminitstate", "yes");
		PropertiesUtils.updateProperties(proper, this.getClass().getResource("/").getPath()+"SystemParams.properties");
		
		addActionMessage("完成初始化系统");
		
		return LOGIN;
	}
	
	@ActionMethodLabel(intercept=InterceptLevel.PROTECTED, methodnote="请求首页")
	public String indexPage() throws Exception{
		
		
		
		return INDEXPAGE_VIEW;
	}
	
	
	
	
	@ActionMethodLabel(intercept=InterceptLevel.PUBLIC, methodnote="生成验证码")
	public String verifyCode() throws Exception{
		getResponse().setDateHeader("Expires", 0);   
        // Set standard HTTP/1.1 no-cache headers.   
		getResponse().setHeader("Cache-Control", "no-store, no-cache, must-revalidate");   
        // Set IE extended HTTP/1.1 no-cache headers (use addHeader).   
		getResponse().addHeader("Cache-Control", "post-check=0, pre-check=0");   
        // Set standard HTTP/1.0 no-cache header.   
		getResponse().setHeader("Pragma", "no-cache");   
        // return a jpeg   
		getResponse().setContentType("image/jpeg"); 
		
		Integer[] codeparam = CheckVerifyCode(codelength, codewidth, codeheight);
		
		Producer kaptcha = new VerifyCodeFactory().getVerifyCode(codeparam[0], codeparam[1], codeparam[2]);
		String capText = kaptcha.createText();
		logger.info("生成的验证码："+capText);
		getSession().setAttribute(Globals.SESSION_VERIFYCODE_KEY, capText);  
		
		ServletOutputStream out = null;
		try {
	        BufferedImage bufimage = kaptcha.createImage(capText); 
	        out = getResponse().getOutputStream();
	        ImageIO.write(bufimage, "PNG", out); 
            out.flush(); 
		}catch (Exception e) {
    			errorrecord.setErrordescribe("生成验证码数据流时产生错误！");
    			getSession().setAttribute(Globals.SESSION_ERRORRECORD, errorrecord);
    			throw e;
        } finally {   
            try {
            	if (out != null)
				out.close();
			} catch (IOException e) {
				addActionError("关闭输出验证码数据流时产生错误！");
				throw e;
			}   
        }
		return null;
	}
	
	
	public String getAdminname() {
		return adminname;
	}
	public void setAdminname(String adminname) {
		this.adminname = adminname;
	}
	public String getAdminpwd() {
		return adminpwd;
	}
	public void setAdminpwd(String adminpwd) {
		this.adminpwd = adminpwd;
	}
	public String getVerifycode() {
		return verifycode;
	}
	public void setVerifycode(String verifycode) {
		this.verifycode = verifycode;
	}
	public String[] getAuthorizationcode() {
		return authorizationcode;
	}
	public void setAuthorizationcode(String[] authorizationcode) {
		this.authorizationcode = authorizationcode;
	}

	public String getCodelength() {
		return codelength;
	}
	public void setCodelength(String codelength) {
		this.codelength = codelength;
	}
	public String getCodewidth() {
		return codewidth;
	}
	public void setCodewidth(String codewidth) {
		this.codewidth = codewidth;
	}
	public String getCodeheight() {
		return codeheight;
	}
	public void setCodeheight(String codeheight) {
		this.codeheight = codeheight;
	}
	
}
